<html>
    <head>
        <title>验证Dto</title>
    </head>
    <body>
        <script>
             /*
                        验证系统用于验证用户输入或客户端对特定控制器动作或服务方法的请求。

                        ABP与ASP.NET核心模型验证系统兼容，其留档中写入的所有内容对于基于ABP的应用程序都已经有效。
                        因此，本文档主要关注ABP功能，而不是重复Microsoft文档。


                        此外，ABP还增加了以下好处：

                            ★、定义 "IValidationEnabled" 以将自动验证添加到任意类。
                                  由于所有应用程序服务都固有地实现了它，因此它们也会自动验证。

                            ★、自动本地化数据注释属性的验证错误。

                            ★、提供可扩展服务来验证方法调用或对象状态

                            ★、提供FluentValiri集成。
                    */

                    /*
                        一、验证Dto

                               本节简要介绍验证系统。有关详细信息，请参阅ASP.NET core 验证文档。 


                               1、数据注解特性(Data Annotation Attributes)) 

                                    使用数据注释是一种以声明方式实现DTO的形式验证的简单方法:
                                        public class CreateBookDto
                                        {
                                            [Required]
                                            [StringLength(100)]
                                            public string Name { get; set; }

                                            [Required]
                                            [StringLength(1000)]
                                            public string Description { get; set; }

                                            [Range(0, 999.99)]
                                            public decimal Price { get; set; }
                                        }
                                    当你将此类用作应用程序服务或控制器的参数时，它会自动验证并抛出本地化验证异常（并由ABP处理）  
                                    
                                    
                               2、IValidateableObject接口
                                    IValidatableObject可以由DTO实现以执行自定义验证逻辑。  
                                    CreateBookDto实现此接口并检查Name是否等于Description并在这种情况下返回验证错误：
                                        
                                                using System.Collections.Generic;
                                                using System.ComponentModel.DataAnnotations;

                                                namespace Acme.BookStore
                                                {
                                                    public class CreateBookDto : IValidatableObject // 实现IValidatableObject接口
                                                    {
                                                        [Required]
                                                        [StringLength(100)]
                                                        public string Name { get; set; }

                                                        [Required]
                                                        [StringLength(1000)]
                                                        public string Description { get; set; }

                                                        [Range(0, 999.99)]
                                                        public decimal Price { get; set; }


                                                        // 自定义验证逻辑
                                                        public IEnumerable<ValidationResult> Validate(
                                                            ValidationContext validationContext)
                                                        {
                                                            if (Name == Description)
                                                            {
                                                                yield return new ValidationResult(
                                                                    "Name and Description can not be the same!",
                                                                    new[] { "Name", "Description" }
                                                                );
                                                            }
                                                        }
                                                    }
                                                }

                                    ★、往自定义验证逻辑中解析服务依赖
                                                如果你需要从依赖注入系统解析服务，你可以使用ValidationContext对象。
                                            
                                            eg:  var myService = validationContext.GetRequiredService<IMyService>();

                                        虽然在Validate方法中解析服务允许任何可能性，但在DTO中实现域验证逻辑并不是一个好的做法。
                                        保持DTO简单。它们的目的是传输数据（DTO：数据传输对象）。
                    */

        </script>
    </body>
</html>